package com.yxy.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.yxy.common.PageResult;
import com.yxy.constant.MessageConstant;
import com.yxy.constant.StatusConstant;
import com.yxy.context.BaseContext;
import com.yxy.exception.HotelAlreadyExistsException;
import com.yxy.exception.HotelSpecsAlreadyExistsException;
import com.yxy.mapper.CollectMapper;
import com.yxy.mapper.HotelMapper;
import com.yxy.pojo.dto.HotelDTO;
import com.yxy.pojo.dto.HotelPageQueryDTO;
import com.yxy.pojo.dto.HotelSpecsDTO;
import com.yxy.pojo.dto.HotelSpecsPageQueryDTO;
import com.yxy.pojo.entity.Hotel;
import com.yxy.pojo.entity.HotelCollect;
import com.yxy.pojo.entity.HotelSpecs;
import com.yxy.pojo.entity.SightsCollect;
import com.yxy.pojo.vo.HotelAdvancedPageQueryVO;
import com.yxy.pojo.vo.HotelPageQueryVO;
import com.yxy.pojo.vo.HotelSpecsPageQueryVO;
import com.yxy.pojo.vo.HotelVO;
import com.yxy.service.HotelService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class HotelServiceImpl implements HotelService {

    @Autowired
    private HotelMapper hotelMapper;
    @Autowired
    private CollectMapper collectMapper;

    /**
     * 分页查询
     *
     * @param hotelPageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(HotelPageQueryDTO hotelPageQueryDTO) {
        PageHelper.startPage(hotelPageQueryDTO.getPage(), hotelPageQueryDTO.getPageSize());
        Page<HotelPageQueryVO> page = hotelMapper.pageQuery(hotelPageQueryDTO);
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 新增
     *
     * @param hotelDTO
     */
    @Override
    public void add(HotelDTO hotelDTO) {
        // 判断酒店名是否存在
        Hotel h = hotelMapper.selectByName(hotelDTO.getName());
        if (h != null) {
            throw new HotelAlreadyExistsException(MessageConstant.HOTEL_ALREADY_EXISTS);
        }

        Hotel hotel = Hotel.builder()
                .name(hotelDTO.getName())
                .address(hotelDTO.getAddress())
                .introduce(hotelDTO.getIntroduce())
                .cover(hotelDTO.getCover())
                .status(StatusConstant.ENABLE)
                .createTime(LocalDateTime.now())
                .createUser(BaseContext.getCurrentId())
                .build();
        hotelMapper.insert(hotel);
    }

    /**
     * 批量删除
     *
     * @param ids
     */
    @Transactional
    @Override
    public void batchDelete(List<Integer> ids) {
        hotelMapper.deleteByIds(ids);
        // 删除对应酒店的规格
        hotelMapper.deleteSpecsByIds(ids);
    }

    /**
     * 修改状态
     *
     * @param id
     * @param status
     */
    @Override
    public void updateStatus(int id, int status) {
        hotelMapper.updateStatus(id, status);
    }

    /**
     * 修改
     *
     * @param hotelDTO
     */
    @Override
    public void update(HotelDTO hotelDTO) {
        Hotel hotel = new Hotel();
        BeanUtils.copyProperties(hotelDTO, hotel);
        hotel.setUpdateTime(LocalDateTime.now());
        hotel.setUpdateUser(BaseContext.getCurrentId());
        hotelMapper.update(hotel);
    }

    /**
     * 分页查询
     *
     * @param hotelSpecsPageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuerySpecs(HotelSpecsPageQueryDTO hotelSpecsPageQueryDTO) {
        PageHelper.startPage(hotelSpecsPageQueryDTO.getPage(), hotelSpecsPageQueryDTO.getPageSize());
        Page<HotelSpecsPageQueryVO> page = hotelMapper.pageQuerySpecs(hotelSpecsPageQueryDTO);
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 新增
     *
     * @param hotelSpecsDTO
     */
    @Override
    public void addSpecs(HotelSpecsDTO hotelSpecsDTO) {
        // 判断规格是否已存在
        HotelSpecs hs = hotelMapper.selectSpecsByNameAndHotelId(hotelSpecsDTO.getName(), hotelSpecsDTO.getHotelId());
        if (hs != null) {
            throw new HotelSpecsAlreadyExistsException(MessageConstant.HOTEL_SPECS_ALREADY_EXISTS);
        }
        HotelSpecs hotelSpecs = new HotelSpecs();
        BeanUtils.copyProperties(hotelSpecsDTO, hotelSpecs);
        hotelMapper.insertHotelSpecs(hotelSpecs);
    }

    /**
     * 更新规格
     *
     * @param hotelSpecsDTO
     */
    @Override
    public void updateSpecs(HotelSpecsDTO hotelSpecsDTO) {
        HotelSpecs hotelSpecs = new HotelSpecs();
        BeanUtils.copyProperties(hotelSpecsDTO, hotelSpecs);
        hotelMapper.updateSpecs(hotelSpecs);
    }

    /**
     * 批量删除
     *
     * @param ids
     */
    @Override
    public void batchDeleteSpecs(List<Integer> ids) {
        hotelMapper.deleteHotelSpecsByIds(ids);
    }

    /**
     * 高级查询
     *
     * @param hotelPageQueryDTO
     * @return
     */
    @Override
    public PageResult advancedPageQuery(HotelPageQueryDTO hotelPageQueryDTO) {
        PageHelper.startPage(hotelPageQueryDTO.getPage(), hotelPageQueryDTO.getPageSize());
        Page<HotelAdvancedPageQueryVO> page = hotelMapper.advancedPageQuery(hotelPageQueryDTO);
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 获取酒店区域
     *
     * @return
     */
    @Override
    public Map<String, List<String>> getHotelArea() {
        List<Hotel> hotelList = hotelMapper.selectAll();
        Map<String, List<String>> map = new HashMap<>();
        for (Hotel hotel : hotelList) {
            String address = hotel.getAddress();
            String[] parts = address.split(" ");
            if (parts.length >= 2) {
                String province = parts[0];
                String city = parts[1];
                // 获取或初始化省份对应的城市列表
                List<String> cities = map.computeIfAbsent(province, k -> new ArrayList<>());
                // 在添加城市前检查是否已存在
                if (!cities.contains(city)) {
                    cities.add(city);
                }
            }
        }
        return map;
    }

    /**
     * 根据id查询酒店
     * @param id
     * @return
     */
    @Override
    public HotelVO getHotelById(int id) {
        Hotel hotel = hotelMapper.selectById(id);
        HotelVO hotelVO = new HotelVO();
        BeanUtils.copyProperties(hotel, hotelVO);
        // 查询用户是否收藏
        HotelCollect hotelCollect = collectMapper.selectByUserIdAndHotelId(BaseContext.getCurrentId(), id);
        // 如果查询为空，表明用户第一次进该景点详情
        if (hotelCollect == null) {
            // 则进行添加操作，值为0（未收藏）
            collectMapper.addHotelCollect(HotelCollect
                    .builder()
                    .userId(BaseContext.getCurrentId())
                    .hotelId(id)
                    .status(StatusConstant.DEFAULT_COLLECT)
                    .build());
        }
        // 把用户的收藏状态添加到返回值中
        hotelVO.setStatus(hotelCollect == null ? StatusConstant.DEFAULT_COLLECT : hotelCollect.getStatus());
        return hotelVO;
    }
}
